﻿using System.Drawing;
using System.Text.RegularExpressions;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using WordCloudSharp;

namespace WordCloudClient.ViewModels
{
    public class ViewGenerateWordCloudViewModel : DataGridCommonVM
    {
        public DelegateCommand ExecuteAddFileDelegateCommand { get; set; }
        public DelegateCommand ExecuteGenerateWordCloudDelegateCommand { get; set; }
        public DelegateCommand ExecuteOpenFileDelegateCommand { get; set; }
        public ViewGenerateWordCloudViewModel(SystemService systemService, WinEditHelper winEditHelper) : base(systemService, winEditHelper)
        {
            ExecuteAddFileDelegateCommand = new DelegateCommand(ExecuteAddFile);
            ExecuteGenerateWordCloudDelegateCommand = new DelegateCommand(async() => await ExecuteGenerateWordCloud());
            ExecuteOpenFileDelegateCommand = new DelegateCommand(ExecuteOpenFile);

        }
        private string _filePath = string.Empty;
        public string FilePath
        {
            get { return _filePath; }
            set
            {
                _filePath = value;
                RaisePropertyChanged(nameof(FilePath));
            }
        }
        private ImageSource? _imagePath;
        public ImageSource? ImagePath
        {
            get { return _imagePath; }
            set
            {
                _imagePath = value;
                RaisePropertyChanged(nameof(ImagePath));
            }
        }
        private List<KeyValuePair<string, int>> _frequenciesList = new();
        public List<KeyValuePair<string, int>> FrequenciesList
        {
            get { return _frequenciesList; }
            set
            {
                _frequenciesList = value;
                RaisePropertyChanged(nameof(FrequenciesList));
            }
        }
        private Visibility _isLoading = Visibility.Collapsed;
        public Visibility IsLoading
        {
            get { return _isLoading; }
            set
            {
                _isLoading = value;
                RaisePropertyChanged(nameof(IsLoading));
            }
        }
        private string _loadingLabel = "数据加载中...";
        public string LoadingLabel
        {
            get { return _loadingLabel; }
            set
            {
                _loadingLabel = value;
                RaisePropertyChanged(nameof(LoadingLabel));
            }
        }
        private WordCloud? wc;
        public RuleEntity RuleEntity { get; set; } = new();
        public override void LoadData()
        {
            FilePath = INIFileLauncher.IniReadValue("LastSelection", "LastFilePath");
            if (string.IsNullOrEmpty(FilePath))
            {
                FilePath = "请选择一个文件";
            }
        }
        public void ExecuteAddFile()
        {
            FilePath = CommonHelper.GetFileAddress("打开文件", "");
            INIFileLauncher.IniWriteValue("LastSelection", "LastFilePath", FilePath);
        }
        public void LoadRule()
        {
            RuleEntity.MaxCount = Convert.ToInt32(INIFileLauncher.IniReadValue("Rule", "MaxCount"));
            RuleEntity.Height = Convert.ToInt32(INIFileLauncher.IniReadValue("Rule", "Height"));
            RuleEntity.Width = Convert.ToInt32(INIFileLauncher.IniReadValue("Rule", "Width"));
            RuleEntity.FilterLength = Convert.ToInt32(INIFileLauncher.IniReadValue("Rule", "FilterLength"));
            RuleEntity.MaskImagePath = INIFileLauncher.IniReadValue("Rule", "MaskImagePath");
        }
        public async Task ExecuteGenerateWordCloud()
        {
            if (!File.Exists(FilePath))
            {
                MessageTips.ErrorMessage("文件路径不存在，请检查！");
                return;
            }
            string imageName = DateTime.Now.ToString("yyyyMMddHHmmss");
            await Task.Run(() =>
            {
                IsLoading = Visibility.Visible;
                LoadRule();
                System.Drawing.Image? maskImg = null;
                if (!string.IsNullOrEmpty(RuleEntity.MaskImagePath))
                {
                    if (File.Exists(RuleEntity.MaskImagePath))
                    {
                        maskImg = System.Drawing.Image.FromFile(RuleEntity.MaskImagePath);
                    }
                    else
                    {
                        MessageTips.ErrorMessage("词云外观文件不存在，请到“词云规则”中重新配置！");
                        return;
                    }
                }
                string context = CommonHelper.ReadWordDocument(FilePath);
                Dictionary<string, int> frequencies;
                frequencies = new Dictionary<string, int>();
                string[] words = Regex.Split(context, @"\W+");
                Regex r = new(@"[\u4e00-\u9fa5]");
                foreach (string word in words)
                {
                    if (word == "" || word.Length <= RuleEntity.FilterLength || r.IsMatch(word) || _systemService.IsExistFilterWords(word))
                    {
                        continue;
                    }
                    //3. 添加或更新映射
                    if (frequencies.ContainsKey(word))
                    {
                        frequencies[word]++;
                    }
                    else
                    {
                        frequencies[word] = 1;
                    }
                }
                List<string> wordName = new();
                List<int> wordCount = new();
                List<KeyValuePair<string, int>> list = frequencies.OrderByDescending(f => f.Value).ToList();
                FrequenciesList = list;
                int maxCount = list.Count;
                if (maxCount > RuleEntity.MaxCount)
                {
                    maxCount = RuleEntity.MaxCount;
                }
                for (int i = 0; i < maxCount; i++)
                {
                    wordName.Add(list[i].Key);
                    wordCount.Add(list[i].Value);
                }
                wc = new WordCloud(RuleEntity.Width, RuleEntity.Height, mask: maskImg, allowVerical: true, fontname: "YouYuan");
                wc.Draw(wordName, wordCount).Save($"./Image/{imageName}.png");
                wc.Dispose();
                IsLoading = Visibility.Collapsed;
            });
            ImagePath = new BitmapImage(new Uri(CommonHelper.UrlRelativeToAbsolute($"./Image/{imageName}.png"), UriKind.Absolute));
        }
        public static void ExecuteOpenFile()
        {
            CommonHelper.OpenFileByExplorer(CommonHelper.UrlRelativeToAbsolute("./Image"));
        }
    }
}
